from flask import *
from json import dumps, load
from datetime import datetime
import os, time

def formatTime(atime):
    import time
    return time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(atime))

app = Flask(__name__)
app.secret_key = 'Frank666!Ry6!'

users = load(open('./data/user.json', 'r'))

@app.errorhandler(404)
def re404(e):
    return render_template("404.html", user=session.get("username")), 404
@app.errorhandler(403)
def re403(e):
    return render_template("403.html", user=session.get("username")), 403

@app.route('/')
def rootindex():
    return redirect('/home')

@app.route('/home')
def home():
    username = session.get("username")
    if username not in users and username:
        return redirect('/login')
    return render_template("index.html", user=username)

@app.route('/favicon.ico')
def icon():
    return send_file('favicon.ico', mimetype='image/vnd.microsoft.icon')

@app.route('/login', methods=['GET', 'POST'])
def login():
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']

        if username in users and users[username] == password:
            session['username'] = username
            return redirect("/")
        else:
            flash('Invalid username or password', 'error')
            return redirect(url_for('login'))

    return render_template('login.html', user=session.get("username"))

@app.route('/file', methods=['GET', 'POST'])
def file():
    username = session.get("username")
    if username not in users:
        return redirect('/login')
    app.config['UPLOAD_FOLDER'] = os.path.join("./data/file/", username)
    if not os.path.exists(app.config['UPLOAD_FOLDER']):
        os.makedirs(app.config['UPLOAD_FOLDER'])
    if request.method == 'POST':
        if 'file' not in request.files:
            return redirect('/file')
        file = request.files['file']
        if file.filename == '':
            return redirect('/file')
        file_path = os.path.join(app.config['UPLOAD_FOLDER'], file.filename)
        file.save(file_path)
        return redirect('/file')
    files = os.listdir(app.config['UPLOAD_FOLDER'])
    return render_template('file.html', user=username, files=files)

@app.route('/file/<username>/<filename>')
def files_get(username, filename):
    user = session.get("username")
    if user not in users:
        return redirect('/login')
    if user != username:
        return abort(403)
    path = os.path.join('./data/file', username)
    if not os.path.exists(path):
        os.makedirs(path)
    file_path = os.path.join(path, filename)
    if not os.path.exists(file_path):
        abort(404)
    if request.args.get('mode') == "delete":
        os.remove(file_path) 
    else:
        return send_file(file_path)
    return redirect('/file')

@app.route('/note')
def note():
    username = session.get("username")
    if username not in users:
        return redirect('/login')
    path = os.path.join("./data/note", username)
    if not os.path.exists(path):
        os.makedirs(path)
    notes = []
    for note in os.listdir(path):
        note_path = os.path.join(path, note)
        if os.path.isdir(note_path):
            with open(os.path.join(note_path, 'info.json'), "r", encoding="utf-8") as f:
                info = load(f)
            notes.append(info)
    notes.sort(key=lambda x: x['CreateTime'], reverse=True)
    return render_template('note.html', user=username, notes=notes)

@app.route('/note/add/<username>', methods=['GET', 'POST'])
def note_add(username):
    user = session.get("username")
    if user != username:
        abort(403)
    if request.method == "POST":
        title = request.form['title']
        content = request.form['content']
        path = f"data/note/{username}"
        NotePath = f"{path}/{title}"
        if not os.path.exists(NotePath):
            os.makedirs(NotePath)
        NowTime = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        InfoDict = {"title": title, "CreateTime": NowTime, "Author": username}
        with open(f"{NotePath}/info.json", "w", encoding="utf-8") as f:
            f.write(dumps(InfoDict))
        with open(f"{NotePath}/content.txt", "w", encoding="utf-8", newline='') as f:
            f.write(content)
        return redirect(f'/note/share/{username}/{title}')
    return render_template('note_edit.html', user=user, title="", content="")

@app.route('/note/update/<username>/<title>', methods=['GET', 'POST'])
def note_edit(username, title):
    username = session.get("username")
    if username not in users:
        return redirect('/login')
    path = f"data/note/{username}/{title}"
    if not os.path.exists(path):
        abort(404)
    if request.method == 'POST':
        title = request.form['title']
        content = request.form['content']

        return redirect(f"/note/{username}/{title}")
    with open(f"{path}/info.json", "r", encoding="utf-8") as f:
        title = load(f)["title"]
    with open(f"{path}/content.txt", "r", encoding="utf-8") as f:
        content = f.read()
    
    return render_template('note_edit.html', user=username, title=title, content=content)

@app.route('/note/share/<username>/<title>')
def note_get(username, title):
    user = session.get("username")
    if user != username:
        abort(403)
    path = f"data/note/{username}/{title}"
    if not os.path.exists(path):
        abort(404)

    with open(f"{path}/info.json", "r", encoding="utf-8") as f:
        info = load(f)
    with open(f"{path}/content.txt", "r", encoding="utf-8") as f:
        content = f.read()
    return render_template('note_share.html', user=user, info=info, content=content)

@app.route('/note/delete/<username>/<title>')
def note_delete(username, title):
    user = session.get("username")
    if user != username:
        abort(403)
    path = f"data/note/{username}/{title}"
    if not os.path.exists(path):
        abort(404)
    os.remove(f"{path}/info.json")
    os.remove(f"{path}/content.txt")
    os.rmdir(path)
    return redirect('/note')

@app.route('/resource', methods=['GET', 'POST'])
def resource():
    username = session.get('username')
    if request.method == 'POST':
        if username != 'root':
            abort(403)
        if 'file' not in request.files:
            return redirect('/resource')
        file = request.files['file']
        if file.filename == '':
            return redirect('/resource')
        file_path = os.path.join('./data/resource', file.filename)
        file.save(file_path)
    files = os.listdir('./data/resource')
    return render_template('resource.html', user=username, files=files)

@app.route('/resource/<filename>')
def resource_get(filename):
    file_path = os.path.join('./data/resource', filename)
    if not os.path.exists(file_path):
        abort(404)
    if request.args.get('mode') == "delete":
        if session.get('username') == 'root':
            abort(403)
        os.remove(file_path)
        return redirect('/resource')
    return send_file(file_path)

@app.route('/page/<pagename>')
def page(pagename):
    path = f"./data/pages/{pagename}"
    if not os.path.exists(path):
        abort(404)
    
    with open(path, "r", encoding="utf-8") as f:
        content = f.read()
    return content

@app.route('/about')
def about():
    return render_template('about.html', user=session.get("username"))

@app.route('/cons')
def console():
    if session.get('username') != 'root':
        return abort(403)
    return render_template('console.html', user=session.get("username"))

@app.route('/cons/file')
def file_console():
    if session.get('username') != 'root':
        abort(403)
    path = request.args.get('path')
    if not os.path.exists(path):
        abort(404)
    formatted = os.path.normpath(path)
    if formatted[-1] == ':':
        formatted += '\\'
    if formatted != path:
        return redirect(f'/cons/file?path={formatted}')
    path = formatted
    if os.path.isfile(path):
        return send_file(path)
    files = os.listdir(path)
    result = []
    for file in files:
        ipath = os.path.join(path, file)
        about_file = os.stat(ipath)
        item = (file, ipath, os.path.isfile(ipath),
                about_file.st_size,
                formatTime(about_file.st_ctime))
        result.append(item)
    return render_template('File_manager.html', path=path, files=result)

@app.route('/cons/page', methods=['GET', 'POST'])
def page_console():
    if session.get('username') != 'root':
        abort(403)
    if request.method == 'POST':
        title = request.form['title']
        content = request.form['content']
        path = f"./data/pages/{title}.html"
        with open(path, "w", encoding="utf-8") as f:
            f.write(content)
        return redirect('/cons/page')
    return render_template('Page_manager.html', user=session.get("username"), pages=os.listdir("./data/pages/"))

@app.route('/logout')
def logout():
    session.pop('username', None)
    return redirect("/home")

if __name__ == '__main__':
    app.run(debug=True, port=80, host='0.0.0.0')
